import React, {Component, createContext, useContext} from 'react';
import ReactDOM from 'react-dom';
import Proptypes from 'prop-types'

//定义context 全局属性
const themes = {
    light:{
        background: '#fff',
        color:'#000'
    },
    dark:{
        background: '#000',
        color:'#fff'
    }
}
const ThemeContext = createContext(themes.light);
const ModalContext = createContext(null);

/*定义模态框组件*/
class ModalContainer extends Component{
    constructor(props) {
        super(props);
        this.el = document.createElement('div')
        this.el.style.cssText = "position: fixed;" +
            "top: 0;"+
            "background:rgba(0,0,0,.5); " +
            "width:100%;" +
            "height:100%;" +
            "display:flex;" +
            "justify-content: center;" +
            "align-items: center;";
    }

    componentDidMount() {
        document.getElementById('root').appendChild(this.el)
    }

    componentWillUnmount() {
        document.getElementById('root').removeChild(this.el)
    }

    render() {
        return ReactDOM.createPortal(this.props.children,this.el)
    }
}
function ModalContent(props) {
    let {toggleModal} = useContext(ModalContext)
    return (
        <div style={{background:'#fff',height:'50px'}}>
            <p>提示：你点击了模态框。</p><br/>
            <button onClick={toggleModal}>确定</button>
        </div>
    )
}

/* 显示context值 ui组件 */
function Themeshow(props) {
    //使用Context.Consumer接收context
    return (
        <ThemeContext.Consumer>
            {value=>(<p>(Consumer方式)传过来的context为：{JSON.stringify(value.theme)}</p>)}
        </ThemeContext.Consumer>
    )
}
/* 显示context值 ui组件 */
function Themeshow2(props) {
    //使用hooks useContext接收context
    let value = useContext(ThemeContext)
    return (
            <p>(hook方式)传过来的context为：{JSON.stringify(value.theme)}</p>
    )
}

/* 主题UI组件 */
class Thememain extends Component {

    //绑定context全局属性
    static contextType = ThemeContext;

    componentDidMount() {
        console.log('组件挂载');
    }

    componentWillUnmount() {
        console.log('组件卸载')
    }

    handleChange = () => {
        this.context.setTheme()
    }

    render() {
        return (
            <div style={{padding:'20px 10px', ...this.context.theme}}>
                <Themeshow></Themeshow>
                <Themeshow2></Themeshow2>
                <button onClick={this.handleChange}>点我切换主题</button>
            </div>
        )
    }

}

/* 插槽模拟 组件 */
function SlotContainer1(props) {
    return (
        <div>
            <header>{props.children.header?props.children.header():'默认的header'}</header>
            <div>{props.children.body?props.children.body():'默认的body'}</div>
            <footer>{props.children.footer?props.children.footer():'默认的footer'}</footer>
        </div>
    )
}
/* -----------------开始--------------------- */
/* 自定义slot组件 */
function Slot(props) {
    let {name, render, children} = props;
    render = Array.isArray(render)?render:[render];

    if(name){
        //具名插槽
        if(render){
            let arr = render.filter(d=>d.props.slot===name && d.props.children)
            return arr.length?arr:children;
        }else{
            //默认插槽
            return children
        }
    }else{
        //普通插槽
        if(render){
            let arr = render.filter(d=>!d.props.slot)
            return arr?arr:children;
        }else{
            //默认插槽
            return children
        }

    }
}
Slot.propTypes = {
    name: Proptypes.string,
    render:Proptypes.array
}
/* 自定义template组件 */
function Template(props) {
    return props.children?props.children:null
}
/* -----------------结束--------------------- */
function SlotContainer2(props) {
    return (
        <div>
            <h2>这是我自己定义的插槽实验室</h2>
            <Slot render={props.children}>这是插槽默认的内容</Slot>
            <p>这是一个段落</p>
            <Slot render={props.children} name="header">这是插槽默认的内容</Slot>
        </div>
    )
}


/* Test 主页面容器组件*/
class Test extends Component {

    //开发工具组件命名
    static displayName = '测试';

    //PropTypes类型检查
    static defaultProps = {
        name: '默认的props-name'
    }
    static propTypes = {
        name: Proptypes.string.isRequired
    }

    //三大属性：状态state
    state = {
        hasErr: false,
        msg: '这是state状态的msg',
        theme: themes.dark,
        modalShow: false
    }

    //方法
    handleClick = () => {
        //使用setState修改状态 ，函数方式
        this.setState((state)=>({hasErr:!state.hasErr}))

        //使用setState修改状态 ，对象方式
        // this.setState({hasErr:!this.state.hasErr})
    }
    setTheme = () => {
        this.setState({theme:this.state.theme === themes.dark?themes.light:themes.dark})
    }
    toggleModal = () => {
        this.setState(state=>({modalShow:!state.modalShow}))
    }

    //生命周期
    componentDidUpdate(prevProps, prevState, snapshot) {
        //状态修改时触发
        // console.log(prevProps,prevState)
    }

    componentDidMount() {
        //组件被挂载时触发
        console.dir(this.props.children);
    }

    render() {
        let {hasErr, msg, theme, modalShow} = this.state;
        //三大属性：props属性
        let {name, children} = this.props;

        if (hasErr) {
            return (
                <div>
                    <h1>Something is terrible!</h1>
                    <button onClick={this.handleClick}>点我改变state</button>
                </div>
            )
        }
        if(modalShow) {

            return (
                <ModalContext.Provider value={{toggleModal:this.toggleModal}}>
                    <ModalContainer>
                        <ModalContent></ModalContent>
                    </ModalContainer>
                </ModalContext.Provider>
            )
        }

        return (
            <React.Fragment>
                <ThemeContext.Provider value={{theme, setTheme:this.setTheme}}>
                    <h1 style={{color:'red'}}>State: {msg}</h1>
                    <h1>Props: {name}</h1>
                    <div style={{border:'1px solid', padding:'20px 10px'}}>
                        <h3>将自己的子元素显示出来</h3>
                        {children}
                    </div>
                    <br/>
                    <Thememain></Thememain>
                </ThemeContext.Provider>
                <br/>
                <button onClick={this.handleClick}>点我改变state</button>
                &nbsp;&nbsp;&nbsp;
                <button onClick={this.toggleModal}>点我弹出模态框</button>
                <div style={{height:'30px'}}></div>
                <h3>插槽模拟实验</h3>
                <SlotContainer1>
                    {{
                        header:()=>(<h1>自定义的header</h1>),
                        // body: ()=>('自定义的body'),
                        footer:()=>('自定义的footer')
                    }}
                </SlotContainer1>
                <br/>
                <hr/>
                <br/>
                <SlotContainer2>
                    <Template slot="header"></Template>
                    <p>床前明月光，疑是地上霜。</p>
                </SlotContainer2>
                <br/>
                <br/>
            </React.Fragment>
        )
    }
}

export default Test